<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Template types</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
  $(document).ready(function() { init_search(); });
/* @license-end */
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectlogo"><img alt="Logo" src="aslogo_small.png"/></td>
  <td id="projectalign">
   <div id="projectname">AngelScript
   </div>
  </td>
    <td>        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <span id="MSearchSelect"                onmouseover="return searchBox.OnSearchSelectShow()"                onmouseout="return searchBox.OnSearchSelectHide()">&#160;</span>
          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
          </span>
        </div>
</td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.6 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(document).ready(function(){initNavTree('doc_adv_template.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>

<div><div class="header">
  <div class="headertitle"><div class="title">Template types </div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>A template type in AngelScript works similarly to how templates work in C++. The scripts will be able to instantiate different forms of the template type by specifying which subtype that should be used. The methods for the instance will then be adapted to this subtype, so that the correct handling of parameters and return types will be applied.</p>
<p>The implementation of the template type is not a C++ template though, instead it must be implemented as a generic class that can determine what to do dynamically at runtime based on the subtype for which it was instantiated. This is obviously a lot less efficient than having specific implementations for each type, and for that reason AngelScript permits the application to register a template specialization where the extra performance is needed.</p>
<p>This gives the best of both worlds, performance where the subtype is known before hand, and support for all other types that cannot be pre-determined.</p>
<h1><a class="anchor" id="doc_adv_template_1"></a>
Registering the template type</h1>
<p>Template types can be either <a class="el" href="doc_reg_basicref.html">reference types</a> or <a class="el" href="doc_register_val_type.html">value types</a>. Both are registered in a similar manner with only a few differences.</p>
<p>The name of the type is formed by the name of the template type plus the name of the subtype with angle brackets. Multiple subtypes can be informed, separated by comma. The type flag asOBJ_TEMPLATE must used to tell AngelScript that it is a template type that is being registered.</p>
<div class="fragment"><div class="line"><span class="comment">// Register the template type as a garbage collected reference type</span></div>
<div class="line">r = engine-&gt;RegisterObjectType(<span class="stringliteral">&quot;myTemplate&lt;class T&gt;&quot;</span>, 0, <a class="code hl_enumvalue" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aa9450e038342b36c745858d2e5ae4b861">asOBJ_REF</a> | <a class="code hl_enumvalue" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aacc1d835f9c25043cef86026a4aa6a470">asOBJ_GC</a> | <a class="code hl_enumvalue" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aae8de459b4106475aa8766edb5b088aac">asOBJ_TEMPLATE</a>); assert( r &gt;= 0 );</div>
<div class="line"> </div>
<div class="line"><span class="comment">// Register another template type as a value type</span></div>
<div class="line">r = engine-&gt;RegisterObjectType(<span class="stringliteral">&quot;myValueTemplate&lt;class T&gt;&quot;</span>, <span class="keyword">sizeof</span>(MyValueTempl), <a class="code hl_enumvalue" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aa9fc16a8ac0f30f9ff9c6568e0b7be91d">asOBJ_VALUE</a> | <a class="code hl_enumvalue" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aae8de459b4106475aa8766edb5b088aac">asOBJ_TEMPLATE</a> | asGetTypeTraits&lt;MyValueTempl&gt;()); assert( r &gt;= 0 );</div>
<div class="ttc" id="aangelscript_8h_html_a855d86fa9ee15b9f75e553ee376b5c7aa9450e038342b36c745858d2e5ae4b861"><div class="ttname"><a href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aa9450e038342b36c745858d2e5ae4b861">asOBJ_REF</a></div><div class="ttdeci">@ asOBJ_REF</div><div class="ttdoc">A reference type.</div><div class="ttdef"><b>Definition:</b> angelscript.h:254</div></div>
<div class="ttc" id="aangelscript_8h_html_a855d86fa9ee15b9f75e553ee376b5c7aa9fc16a8ac0f30f9ff9c6568e0b7be91d"><div class="ttname"><a href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aa9fc16a8ac0f30f9ff9c6568e0b7be91d">asOBJ_VALUE</a></div><div class="ttdeci">@ asOBJ_VALUE</div><div class="ttdoc">A value type.</div><div class="ttdef"><b>Definition:</b> angelscript.h:256</div></div>
<div class="ttc" id="aangelscript_8h_html_a855d86fa9ee15b9f75e553ee376b5c7aacc1d835f9c25043cef86026a4aa6a470"><div class="ttname"><a href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aacc1d835f9c25043cef86026a4aa6a470">asOBJ_GC</a></div><div class="ttdeci">@ asOBJ_GC</div><div class="ttdoc">A garbage collected type. Only valid for reference types.</div><div class="ttdef"><b>Definition:</b> angelscript.h:258</div></div>
<div class="ttc" id="aangelscript_8h_html_a855d86fa9ee15b9f75e553ee376b5c7aae8de459b4106475aa8766edb5b088aac"><div class="ttname"><a href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aae8de459b4106475aa8766edb5b088aac">asOBJ_TEMPLATE</a></div><div class="ttdeci">@ asOBJ_TEMPLATE</div><div class="ttdoc">A template type.</div><div class="ttdef"><b>Definition:</b> angelscript.h:266</div></div>
</div><!-- fragment --><p>The template type doesn't have to be <a class="el" href="doc_gc_object.html">garbage collected</a>, but since you may not know which subtypes it will be instantiated for, it is usually best to implement that support.</p>
<p>When registering the behaviours, methods, and properties for the template type the type is identified with the name and subtype within angle brackets, but without the class token, e.g. <code>myTemplate&lt;T&gt;</code>. The sub type is identified by just the name of the subtype as it was declared in the call to RegisterObjectType.</p>
<p>The factory/construct behaviour for the template type is also different. In order for the implementation to know which subtype it is instantiated for, the factory/constructor receives the <a class="el" href="classas_i_type_info.html">asITypeInfo</a> of the template instance as a hidden first parameter. When registering the factory/constructor this hidden parameter is reflected in the declaration, for example as <code>int &amp;in</code>.</p>
<div class="fragment"><div class="line"><span class="comment">// Register the factory behaviour</span></div>
<div class="line">r = engine-&gt;RegisterObjectBehaviour(<span class="stringliteral">&quot;myTemplate&lt;T&gt;&quot;</span>, <a class="code hl_enumvalue" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a0b3db16eea35213b6f41f8d19dc1bd4c">asBEHAVE_FACTORY</a>, <span class="stringliteral">&quot;myTemplate&lt;T&gt;@ f(int&amp;in)&quot;</span>, <a class="code hl_define" href="angelscript_8h.html#a153aee5a6228913a469b6e6867e54efb">asFUNCTIONPR</a>(myTemplateFactory, (<a class="code hl_class" href="classas_i_type_info.html">asITypeInfo</a>*), myTemplate*), <a class="code hl_enumvalue" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4">asCALL_CDECL</a>); assert( r &gt;= 0 );</div>
<div class="line"> </div>
<div class="line"><span class="comment">// Register the construct behaviour</span></div>
<div class="line">r = engine-&gt;RegisterObjectBehaviour(<span class="stringliteral">&quot;myValueTemplate&lt;T&gt;&quot;</span>, <a class="code hl_enumvalue" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5aa4cf235bfbf72ec03d0f651cea324101">asBEHAVE_CONSTRUCT</a>, <span class="stringliteral">&quot;void f(int&amp;in)&quot;</span>, <a class="code hl_define" href="angelscript_8h.html#a153aee5a6228913a469b6e6867e54efb">asFUNCTIONPR</a>(myValueTemplConstructor, (<a class="code hl_class" href="classas_i_type_info.html">asITypeInfo</a>*, <span class="keywordtype">void</span>*), <span class="keywordtype">void</span>), <a class="code hl_enumvalue" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4ac08652c72f1cc0dc81c37812fab0e253">asCALL_CDECL_OBJLAST</a>); assert( r &gt;= 0 );</div>
<div class="ttc" id="aangelscript_8h_html_a153aee5a6228913a469b6e6867e54efb"><div class="ttname"><a href="angelscript_8h.html#a153aee5a6228913a469b6e6867e54efb">asFUNCTIONPR</a></div><div class="ttdeci">#define asFUNCTIONPR(f, p, r)</div><div class="ttdoc">Returns an asSFuncPtr representing the function specified by the name, parameter list,...</div><div class="ttdef"><b>Definition:</b> angelscript.h:694</div></div>
<div class="ttc" id="aangelscript_8h_html_a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4"><div class="ttname"><a href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4">asCALL_CDECL</a></div><div class="ttdeci">@ asCALL_CDECL</div><div class="ttdoc">A cdecl function.</div><div class="ttdef"><b>Definition:</b> angelscript.h:230</div></div>
<div class="ttc" id="aangelscript_8h_html_a3ec92ea3c4762e44c2df788ceccdd1e4ac08652c72f1cc0dc81c37812fab0e253"><div class="ttname"><a href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4ac08652c72f1cc0dc81c37812fab0e253">asCALL_CDECL_OBJLAST</a></div><div class="ttdeci">@ asCALL_CDECL_OBJLAST</div><div class="ttdoc">A cdecl function that takes the object pointer as the last parameter.</div><div class="ttdef"><b>Definition:</b> angelscript.h:238</div></div>
<div class="ttc" id="aangelscript_8h_html_a7e38df5b10ec8cbf2a688f1d114097c5a0b3db16eea35213b6f41f8d19dc1bd4c"><div class="ttname"><a href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a0b3db16eea35213b6f41f8d19dc1bd4c">asBEHAVE_FACTORY</a></div><div class="ttdeci">@ asBEHAVE_FACTORY</div><div class="ttdoc">Factory.</div><div class="ttdef"><b>Definition:</b> angelscript.h:366</div></div>
<div class="ttc" id="aangelscript_8h_html_a7e38df5b10ec8cbf2a688f1d114097c5aa4cf235bfbf72ec03d0f651cea324101"><div class="ttname"><a href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5aa4cf235bfbf72ec03d0f651cea324101">asBEHAVE_CONSTRUCT</a></div><div class="ttdeci">@ asBEHAVE_CONSTRUCT</div><div class="ttdoc">Constructor.</div><div class="ttdef"><b>Definition:</b> angelscript.h:358</div></div>
<div class="ttc" id="aclassas_i_type_info_html"><div class="ttname"><a href="classas_i_type_info.html">asITypeInfo</a></div><div class="ttdoc">The interface for describing types This interface is used to describe the types in the script engine.</div><div class="ttdef"><b>Definition:</b> angelscript.h:3704</div></div>
</div><!-- fragment --><p>The list factory/constructor, used to instantiate objects with initialization lists, is registered in the same way, i.e.:</p>
<div class="fragment"><div class="line"><span class="comment">// Register the list factory behaviour</span></div>
<div class="line">r = engine-&gt;RegisterObjectBehaviour(<span class="stringliteral">&quot;myTemplate&lt;T&gt;&quot;</span>, <a class="code hl_enumvalue" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5aea078bc3b877ce33a2335e78ddb4938d">asBEHAVE_LIST_FACTORY</a>, <span class="stringliteral">&quot;myTemplate&lt;T&gt;@ f(int&amp;in, uint)&quot;</span>, <a class="code hl_define" href="angelscript_8h.html#a153aee5a6228913a469b6e6867e54efb">asFUNCTIONPR</a>(myTemplateListFactory, (<a class="code hl_class" href="classas_i_type_info.html">asITypeInfo</a>*, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>), myTemplate*), <a class="code hl_enumvalue" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4">asCALL_CDECL</a>); assert( r &gt;= 0 );</div>
<div class="line"> </div>
<div class="line"><span class="comment">// Register the list constructor behaviour</span></div>
<div class="line">r = engine-&gt;RegisterObjectBehaviour(<span class="stringliteral">&quot;myValueTemplate&lt;T&gt;&quot;</span>, <a class="code hl_enumvalue" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a04c0b561986c6814e8a54ce3679178a2">asBEHAVE_LIST_CONSTRUCT</a>, <span class="stringliteral">&quot;void f(int&amp;in, uint)&quot;</span>, <a class="code hl_define" href="angelscript_8h.html#a153aee5a6228913a469b6e6867e54efb">asFUNCTIONPR</a>(myValueTemplListConstruct, (<a class="code hl_class" href="classas_i_type_info.html">asITypeInfo</a>*, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>, <span class="keywordtype">void</span>*), <span class="keywordtype">void</span>), <a class="code hl_enumvalue" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4ac08652c72f1cc0dc81c37812fab0e253">asCALL_CDECL_OBJLAST</a>); assert( r &gt;= 0 );</div>
<div class="ttc" id="aangelscript_8h_html_a7e38df5b10ec8cbf2a688f1d114097c5a04c0b561986c6814e8a54ce3679178a2"><div class="ttname"><a href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a04c0b561986c6814e8a54ce3679178a2">asBEHAVE_LIST_CONSTRUCT</a></div><div class="ttdeci">@ asBEHAVE_LIST_CONSTRUCT</div><div class="ttdoc">Constructor used exclusively for initialization lists.</div><div class="ttdef"><b>Definition:</b> angelscript.h:360</div></div>
<div class="ttc" id="aangelscript_8h_html_a7e38df5b10ec8cbf2a688f1d114097c5aea078bc3b877ce33a2335e78ddb4938d"><div class="ttname"><a href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5aea078bc3b877ce33a2335e78ddb4938d">asBEHAVE_LIST_FACTORY</a></div><div class="ttdeci">@ asBEHAVE_LIST_FACTORY</div><div class="ttdoc">Factory used exclusively for initialization lists.</div><div class="ttdef"><b>Definition:</b> angelscript.h:368</div></div>
</div><!-- fragment --><p>Remember that since the subtype must be determined dynamically at runtime, it is not possible to declare functions to receive the subtype by value, nor to return it by value. Instead you'll have to design the methods and behaviours to take the type by reference. It is possible to use object handles, but then the script engine won't be able to instantiate the template type for primitives and other values types.</p>
<p>The same goes for object properties. Templates can have properties just like any other class, but the properties must not be of the template subtype, since it is not known at the time of registration the size of this type.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="doc_addon_array.html">array template object</a></dd></dl>
<h2><a class="anchor" id="doc_adv_template_1_1"></a>
On subtype replacement for template instances</h2>
<p>When a template type is instanced in a declaration, e.g. a variable, the compiler enumerates all the members of the template type to verify if any subtype is used which requires replacement. In most cases the replacement is a direct one-to-one mapping, but in cases where the subtype is used as a const parameter reference, then an additional instruction may be needed to get the expected behaviour.</p>
<p>The following shows a method registered to take the subtype T as a const ref.</p>
<div class="fragment"><div class="line">r = engine-&gt;RegisterObjectMethod(<span class="stringliteral">&quot;array&lt;T&gt;&quot;</span>, <span class="stringliteral">&quot;int find(const T&amp;in value) const&quot;</span>, ...); </div>
</div><!-- fragment --><p>If this template is instantiated with a handle as a subtype, e.g. <code>array&lt;Obj@&gt;</code>, then the method will become:</p>
<pre>
  int find(Obj @const &amp;in value) const
</pre><p>This means that that the parameter takes the handle to a non-read only Obj. The actual handle cannot be modified, but the object the handle refers to can still be modified by the method. This in turn makes it impossible for a script to call the method if the handle the script has is read only.</p>
<p>To allow the application developer to say that the method should allow handles to read only objects, a special keyword <code>if_handle_then_const</code> should be used.</p>
<div class="fragment"><div class="line">r = engine-&gt;RegisterObjectMethod(<span class="stringliteral">&quot;array&lt;T&gt;&quot;</span>, <span class="stringliteral">&quot;int find(const T&amp;in if_handle_then_const value) const&quot;</span>, ...); </div>
</div><!-- fragment --><p>Now this becomes:</p>
<pre>
  int find(const Obj @const &amp;in value) const
</pre><p>This means that the parameter takes a const handle to a read only Obj, i.e. both the handle itself and the object instance it refers to cannot be modified by the method. Now the script will be able to call the method both with read only handles and non-read only handles.</p>
<h1><a class="anchor" id="doc_adv_template_4"></a>
Validating template instantiations at compile time</h1>
<p>In order to avoid unnecessary runtime validations of invalid template instantiations, the application should preferably register the <a class="el" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a8c9afe12ff833cd09bd893e1408b9103">asBEHAVE_TEMPLATE_CALLBACK</a> behaviour. This is a special behaviour function that the script engine will invoke every time a new template instance type is generated. The callback function can then perform necessary validations to verify if the type can be handled, and if not tell the engine that the instance isn't supported.</p>
<p>The callback function must be a global function that receives an <a class="el" href="classas_i_type_info.html" title="The interface for describing types This interface is used to describe the types in the script engine.">asITypeInfo</a> pointer, and should return a boolean. If the template instance is valid the return value should be true.</p>
<p>The function should also take a second parameter with an output reference to a boolean. This parameter should be set to true by the function if the template instance should not be garbage collected, which will make AngelScript clear the asOBJ_GC flag for the object type. If the template instance cannot form any circular references, then it doesn't need to be garbage collected, which reduces the work that has to be done by the garbage collector.</p>
<div class="fragment"><div class="line"><span class="comment">// Register the template callback</span></div>
<div class="line"><span class="comment">// Observe that the asITypeInfo pointer argument is represented by the int reference</span></div>
<div class="line">r = engine-&gt;RegisterObjectBehaviour(<span class="stringliteral">&quot;myTemplate&lt;T&gt;&quot;</span>, <a class="code hl_enumvalue" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a8c9afe12ff833cd09bd893e1408b9103">asBEHAVE_TEMPLATE_CALLBACK</a>, <span class="stringliteral">&quot;bool f(int &amp;in, bool&amp;out)&quot;</span>, <a class="code hl_define" href="angelscript_8h.html#a78f8f2c7f1c88b12e74a5ac47b4184ae">asFUNCTION</a>(myTemplateCallback), <a class="code hl_enumvalue" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4">asCALL_CDECL</a>); assert( r &gt;= 0 );</div>
<div class="ttc" id="aangelscript_8h_html_a78f8f2c7f1c88b12e74a5ac47b4184ae"><div class="ttname"><a href="angelscript_8h.html#a78f8f2c7f1c88b12e74a5ac47b4184ae">asFUNCTION</a></div><div class="ttdeci">#define asFUNCTION(f)</div><div class="ttdoc">Returns an asSFuncPtr representing the function specified by the name.</div><div class="ttdef"><b>Definition:</b> angelscript.h:685</div></div>
<div class="ttc" id="aangelscript_8h_html_a7e38df5b10ec8cbf2a688f1d114097c5a8c9afe12ff833cd09bd893e1408b9103"><div class="ttname"><a href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a8c9afe12ff833cd09bd893e1408b9103">asBEHAVE_TEMPLATE_CALLBACK</a></div><div class="ttdeci">@ asBEHAVE_TEMPLATE_CALLBACK</div><div class="ttdoc">Callback for validating template instances.</div><div class="ttdef"><b>Definition:</b> angelscript.h:378</div></div>
</div><!-- fragment --><p>Here's an example callback function:</p>
<div class="fragment"><div class="line"><span class="keywordtype">bool</span> myTemplateCallback(<a class="code hl_class" href="classas_i_type_info.html">asITypeInfo</a> *ot, <span class="keywordtype">bool</span> &amp;dontGarbageCollect)</div>
<div class="line">{</div>
<div class="line">  <span class="comment">// This template will only support primitive types</span></div>
<div class="line">  <span class="keywordtype">int</span> typeId = ot-&gt;<a class="code hl_function" href="classas_i_type_info.html#aa1a56809ce5c340364ecd8beac508eb4">GetSubTypeId</a>();</div>
<div class="line">  <span class="keywordflow">if</span>( typeId &amp; <a class="code hl_enumvalue" href="angelscript_8h.html#ae8c3a67a97321be53181e9ed396ad83aa09eef59280d15a58c75e0c8983a3c3af">asTYPEID_MASK_OBJECT</a> )</div>
<div class="line">  {</div>
<div class="line">    <span class="comment">// The script is attempting to instantiate the </span></div>
<div class="line">    <span class="comment">// template with an object type, this is not allowed.</span></div>
<div class="line">    <span class="keywordflow">return</span> <span class="keyword">false</span>;</div>
<div class="line">  }</div>
<div class="line">  </div>
<div class="line">  <span class="comment">// Tell AngelScript that this instance doesn&#39;t require garbage collection</span></div>
<div class="line">  dontGarbageCollect = <span class="keyword">true</span>;</div>
<div class="line">    </div>
<div class="line">  <span class="comment">// Primitive types are allowed</span></div>
<div class="line">  <span class="keywordflow">return</span> <span class="keyword">true</span>;</div>
<div class="line">}</div>
<div class="ttc" id="aangelscript_8h_html_ae8c3a67a97321be53181e9ed396ad83aa09eef59280d15a58c75e0c8983a3c3af"><div class="ttname"><a href="angelscript_8h.html#ae8c3a67a97321be53181e9ed396ad83aa09eef59280d15a58c75e0c8983a3c3af">asTYPEID_MASK_OBJECT</a></div><div class="ttdeci">@ asTYPEID_MASK_OBJECT</div><div class="ttdoc">If any of these bits are set, then the type is an object.</div><div class="ttdef"><b>Definition:</b> angelscript.h:498</div></div>
<div class="ttc" id="aclassas_i_type_info_html_aa1a56809ce5c340364ecd8beac508eb4"><div class="ttname"><a href="classas_i_type_info.html#aa1a56809ce5c340364ecd8beac508eb4">asITypeInfo::GetSubTypeId</a></div><div class="ttdeci">virtual int GetSubTypeId(asUINT subTypeIndex=0) const =0</div><div class="ttdoc">Returns the type id of the template sub type.</div></div>
</div><!-- fragment --><h1><a class="anchor" id="doc_adv_template_2"></a>
Template specializations</h1>
<p>When registering a template specialization you override the template instance that AngelScript would normally do when compiling a declaration with the template type. This allow the application to register a completely different object with its own implementation for template specializations. Obviously it is recommended that the template specialization is registered so that to the script writer it is transparent, i.e. try to avoid having different method names or behaviours for the template type and template specializations.</p>
<p>With the exception of the type name, a template specialization is registered exactly like a <a class="el" href="doc_register_type.html">normal type</a>. The template specialization must be registered in the same namespace as the template itself.</p>
<div class="fragment"><div class="line"><span class="comment">// Register a template specialization for the float subtype</span></div>
<div class="line">r = engine-&gt;RegisterObjectType(<span class="stringliteral">&quot;myTemplate&lt;float&gt;&quot;</span>, 0, <a class="code hl_enumvalue" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aa9450e038342b36c745858d2e5ae4b861">asOBJ_REF</a>); assert( r &gt;= 0 );</div>
<div class="line">  </div>
<div class="line"><span class="comment">// Register the factory (there are no hidden parameters for specializations)</span></div>
<div class="line">r = engine-&gt;RegisterObjectBehaviour(<span class="stringliteral">&quot;myTemplate&lt;float&gt;&quot;</span>, <a class="code hl_enumvalue" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a0b3db16eea35213b6f41f8d19dc1bd4c">asBEHAVE_FACTORY</a>, <span class="stringliteral">&quot;myTemplate&lt;float&gt;@ f()&quot;</span>, <a class="code hl_define" href="angelscript_8h.html#a153aee5a6228913a469b6e6867e54efb">asFUNCTIONPR</a>(myTemplateFloatFactory, (), myTemplateFloat*), <a class="code hl_enumvalue" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4">asCALL_CDECL</a>); assert( r &gt;= 0 );</div>
</div><!-- fragment --> </div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated on Sun May 21 2023 10:12:40 for AngelScript by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.6 </li>
  </ul>
</div>
</body>
</html>
